/* Copyright (c) [2020] [ylc]. Licensed under Apache-2.0 License. */

#include "i2cDriveM.h"

//io口模拟i2c驱动
//共7个操作IO函数和1个延时需要实现


void i2c_Start(mI2CTypedef_t *i2c){
	i2c->IIC_SDA_H();
	i2c->IIC_Delay();
	i2c->IIC_SCL_H();
	i2c->IIC_Delay();
	i2c->IIC_SDA_L();
	i2c->IIC_Delay();
	i2c->IIC_SCL_L();
#if I2C_FAST == 0
	i2c->IIC_Delay();
#endif
}

void i2c_Stop(mI2CTypedef_t *i2c){
	i2c->IIC_SDA_L();
	i2c->IIC_Delay();
	i2c->IIC_SCL_H();
	i2c->IIC_Delay();
	i2c->IIC_SDA_H();
	i2c->IIC_Delay();					//这个delay不必要，不过加上波形更清晰

}

void i2c_SendByte(mI2CTypedef_t *i2c,u8 _ucByte){
	u8 i;
	/*first bit7 */
	for(i=0;i<8;i++){
		if(_ucByte & 0x80){
			i2c->IIC_SDA_H();
		}
		else{
			i2c->IIC_SDA_L();
		}
		i2c->IIC_Delay();
		i2c->IIC_SCL_H();
		i2c->IIC_Delay();
		i2c->IIC_SCL_L();   
#if I2C_FAST == 0   
		i2c->IIC_Delay();
#endif
		_ucByte <<= 1; 
	}
#if I2C_FAST == 0
	i2c->IIC_SDA_H(); 	//完事了释放SDA总线
	i2c->IIC_Delay();
#endif	
}

u8 i2c_ReadByte(mI2CTypedef_t *i2c){
	u8 i;
	u8 value;
	/*first bit7 */
	value = 0;
#if I2C_FAST == 0
	i2c->IIC_SDA_H();		//读之前肯定是wack，里面已经释放了sda
	i2c->IIC_Delay();
#endif	
	for(i=0;i<8;i++){
		value <<= 1;
		i2c->IIC_Delay();		//允许从机修改sda时间
		i2c->IIC_SCL_H();	//锁定sda
		if(i2c->IIC_READ_SDA()){
			value++;
		}
		i2c->IIC_Delay();
		i2c->IIC_SCL_L();
#if I2C_FAST == 0
		i2c->IIC_Delay();
#endif	
	}
	return value;
}

u8 i2c_WaitAck(mI2CTypedef_t *i2c){
	u8 re;
	u8 count=2;
	i2c->IIC_SDA_H();
	i2c->IIC_Delay();
	i2c->IIC_SCL_H();
	i2c->IIC_Delay();
	do{
		count--;
		if (i2c->IIC_READ_SDA()){
			re = 1;
		}
		else{
			re = 0;
			break;
		}
		i2c->IIC_Delay();
	}while(count>0);
	i2c->IIC_SCL_L();
#if I2C_FAST == 0
	i2c->IIC_Delay();
#endif		
	return re;
}

void i2c_Ack(mI2CTypedef_t *i2c){
	i2c->IIC_SDA_L();
	i2c->IIC_Delay();
	i2c->IIC_SCL_H();
	i2c->IIC_Delay();
	i2c->IIC_SCL_L();
#if I2C_FAST == 0
	i2c->IIC_Delay();
#endif
	i2c->IIC_SDA_H();
}

void i2c_NAck(mI2CTypedef_t *i2c){
	i2c->IIC_SDA_H();
	i2c->IIC_Delay();
	i2c->IIC_SCL_H();
	i2c->IIC_Delay();
	i2c->IIC_SCL_L();
#if I2C_FAST == 0
	i2c->IIC_Delay();
#endif
}

u8 i2c_CheckDevice(mI2CTypedef_t *i2c,u8 _Address){
	u8 ucAck;
	if(i2c->IIC_READ_SDA()&&i2c->IIC_READ_SCL()){
		i2c_Start( i2c );                        
		i2c_SendByte( i2c, _Address | I2C_WR);
		ucAck = i2c_WaitAck( i2c );
		i2c_Stop( i2c );
		return ucAck;
	}
	return 1;
}

void i2c_SdaErrorClear(mI2CTypedef_t *i2c){		//清除SDA总线挂死
	u8 i;
	for(i=0;i<9;i++){
		i2c->IIC_SCL_L();
		i2c->IIC_Delay();
		if(i2c->IIC_READ_SDA()){
			break;
		}
		i2c->IIC_SCL_H();
	}
	i2c->IIC_Delay();
	i2c_Stop(i2c);
}
